﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;

namespace VietNamKey
{
    public static class Encodings
    {
        public static ItemEncoding Unicode = new ItemEncoding("Unicode",
                                                              "a", "á", "à", "ã", "ả", "ạ",
                                                              "ă", "ắ", "ằ", "ẵ", "ẳ", "ặ",
                                                              "â", "ấ", "ầ", "ẫ", "ẩ", "ậ",
                                                              "e", "é", "è", "ẽ", "ẻ", "ẹ",
                                                              "ê", "ế", "ề", "ễ", "ể", "ệ",
                                                              "i", "í", "ì", "ĩ", "ỉ", "ị",
                                                              "o", "ó", "ò", "õ", "ỏ", "ọ",
                                                              "ô", "ố", "ồ", "ỗ", "ổ", "ộ",
                                                              "ơ", "ớ", "ờ", "ỡ", "ở", "ợ",
                                                              "u", "ú", "ù", "ũ", "ủ", "ụ",
                                                              "ư", "ứ", "ừ", "ữ", "ử", "ự",
                                                              "y", "ý", "ỳ", "ỹ", "ỷ", "ỵ",
                                                              "d", "đ",
                                                              "A", "Á", "À", "Ã", "Ả", "Ạ",
                                                              "Ă", "Ắ", "Ằ", "Ẵ", "Ẳ", "Ặ",
                                                              "Â", "Ấ", "Ầ", "Ẫ", "Ẩ", "Ậ",
                                                              "E", "É", "È", "Ẽ", "Ẻ", "Ẹ",
                                                              "Ê", "Ế", "Ề", "Ễ", "Ể", "Ệ",
                                                              "I", "Í", "Ì", "Ĩ", "Ỉ", "Ị",
                                                              "O", "Ó", "Ò", "Õ", "Ỏ", "Ọ",
                                                              "Ô", "Ố", "Ồ", "Ỗ", "Ổ", "Ộ",
                                                              "Ơ", "Ớ", "Ờ", "Ỡ", "Ở", "Ợ",
                                                              "U", "Ú", "Ù", "Ũ", "Ủ", "Ụ",
                                                              "Ư", "Ứ", "Ừ", "Ữ", "Ử", "Ự",
                                                              "Y", "Ý", "Ỳ", "Ỹ", "Ỷ", "Ỵ",
                                                              "D", "Đ"
            );

        public static ItemEncoding TCVN3 = new ItemEncoding("TCVN3",
                                                            "a", "¸", "µ", "·", "¶", "¹",
                                                            "¨", "¾", "»", "½", "¼", "Æ",
                                                            "©", "Ê", "Ç", "É", "È", "Ë",
                                                            "e", "Ð", "Ì", "Ï", "Î", "Ñ",
                                                            "ª", "Õ", "Ò", "Ô", "Ó", "Ö",
                                                            "i", "Ý", "×", "Ü", "Ø", "Þ",
                                                            "o", "ã", "ß", "â", "á", "ä",
                                                            "«", "è", "å", "ç", "æ", "é",
                                                            "¬", "í", "ê", "ì", "ë", "î",
                                                            "u", "ó", "ï", "ò", "ñ", "ô",
                                                            "­", "ø", "õ", "÷", "ö", "ù",
                                                            "y", "ý", "ú", "ü", "û", "þ",
                                                            "d", "®",
                                                            "A", "¸", "µ", "·", "¶", "¹",
                                                            "¡", "¾", "»", "½", "¼", "Æ",
                                                            "¢", "Ê", "Ç", "É", "È", "Ë",
                                                            "E", "Ð", "Ì", "Ï", "Î", "Ñ",
                                                            "£", "Õ", "Ò", "Ô", "Ó", "Ö",
                                                            "I", "Ý", "×", "Ü", "Ø", "Þ",
                                                            "O", "ã", "ß", "â", "á", "ä",
                                                            "¤", "è", "å", "ç", "æ", "é",
                                                            "¥", "í", "ê", "ì", "ë", "î",
                                                            "U", "ó", "ï", "ò", "ñ", "ô",
                                                            "¦", "ø", "õ", "÷", "ö", "ù",
                                                            "Y", "ý", "ú", "ü", "û", "þ",
                                                            "D", "§"
            );

        public static ItemEncoding VNI = new ItemEncoding("VNI Windows",
                                                          "a", "aù", "aø", "aõ", "aû", "aï",
                                                          "aê", "aé", "aè", "aü", "aú", "aë",
                                                          "aâ", "aá", "aà", "aã", "aå", "aä",
                                                          "e", "eù", "eø", "eõ", "eû", "eï",
                                                          "eâ", "eá", "eà", "eã", "eå", "eä",
                                                          "i", "í", "ì", "ó", "æ", "ò",
                                                          "o", "où", "oø", "oõ", "oû", "oï",
                                                          "oâ", "oá", "oà", "oã", "oå", "oä",
                                                          "ô", "ôù", "ôø", "ôõ", "ôû", "ôï",
                                                          "u", "uù", "uø", "uõ", "uû", "uï",
                                                          "ö", "öù", "öø", "öõ", "öû", "öï",
                                                          "y", "yù", "yø", "yõ", "yû", "î",
                                                          "d", "ñ",
                                                          "A", "AÙ", "AØ", "AÕ", "AÛ", "AÏ",
                                                          "AÊ", "AÉ", "AÈ", "AÜ", "AÚ", "AË",
                                                          "AÂ", "AÁ", "AÀ", "AÃ", "AÅ", "AÄ",
                                                          "E", "EÙ", "EØ", "EÕ", "EÛ", "EÏ",
                                                          "EÂ", "EÁ", "EÀ", "EÃ", "EÅ", "EÄ",
                                                          "I", "Í", "Ì", "Ó", "Æ", "Ò",
                                                          "O", "OÙ", "OØ", "OÕ", "OÛ", "OÏ",
                                                          "OÂ", "OÁ", "OÀ", "OÃ", "OÅ", "OÄ",
                                                          "Ô", "ÔÙ", "ÔØ", "ÔÕ", "ÔÛ", "ÔÏ",
                                                          "U", "UÙ", "UØ", "UÕ", "UÛ", "UÏ",
                                                          "Ö", "ÖÙ", "ÖØ", "ÖÕ", "ÖÛ", "ÖÏ",
                                                          "Y", "YÙ", "YØ", "YÕ", "YÛ", "Î",
                                                          "D", "Ñ"
            );

        public static ItemEncoding VIQR = new ItemEncoding("VIQR",
                                                           "a", "a'", "a`", "a~", "a?", "a.",
                                                           "a(", "a('", "a(`", "a(~", "a(?", "a(.",
                                                           "a^", "a^'", "a^`", "a^~", "a^?", "a^.",
                                                           "e", "e'", "e`", "e~", "e?", "e.",
                                                           "e^", "e^'", "e^`", "e^~", "e^?", "e^.",
                                                           "i", "i'", "i`", "i~", "i?", "i.",
                                                           "o", "o'", "o`", "o~", "o?", "o.",
                                                           "o^", "o^'", "o^`", "o^~", "o^?", "o^.",
                                                           "o+", "o+'", "o+`", "o+~", "o+?", "o+.",
                                                           "u", "u'", "u`", "u~", "u?", "u.",
                                                           "u+", "u+'", "u+`", "u+~", "u+?", "u+.",
                                                           "y", "y'", "y`", "y~", "y?", "y.",
                                                           "d", "dd",
                                                           "A", "A'", "A`", "A~", "A?", "A.",
                                                           "A(", "A('", "A(`", "A(~", "A(?", "A(.",
                                                           "A^", "A^'", "A^`", "A^~", "A^?", "A^.",
                                                           "E", "E'", "E`", "E~", "E?", "E.",
                                                           "E^", "E^'", "E^`", "E^~", "E^?", "E^.",
                                                           "I", "I'", "I`", "I~", "I?", "I.",
                                                           "O", "O'", "O`", "O~", "O?", "O.",
                                                           "O^", "O^'", "O^`", "O^~", "O^?", "O^.",
                                                           "O+", "O+'", "O+`", "O+~", "O+?", "O+.",
                                                           "U", "U'", "U`", "U~", "U?", "U.",
                                                           "U+", "U+'", "U+`", "U+~", "U+?", "U+.",
                                                           "Y", "Y'", "Y`", "Y~", "Y?", "Y.",
                                                           "D", "DD"
            );
    	
        public static ItemEncoding[] List = new[] { Unicode, VNI, VIQR, TCVN3 };
                                     //, UnicodeCString, UTF8, NRCDec, NRCHex};

        public static string ConvertFromUnicode(string input, List<string> DestinationEncoding)
        {
        	return Convert(input, Unicode.Value, DestinationEncoding);
        }

        public static string Convert(string input, List<string> SourceEncoding, List<string> DestinationEncoding)
        {
            if (DestinationEncoding == SourceEncoding)
            {
                return input;
            }
            var Source = SourceEncoding.ToArray();
            var Destination = DestinationEncoding.ToArray();
            //Xếp 2 mảng chuyển đổi lại, ưu tiên thay thế các ký tự dài trước
            for (int i = 0; i < Source.Length - 1; i++)
                for (int j = i + 1; j < Source.Length; j++)
                    if (Source[i].Length < Source[j].Length)
                    {
                        var t1 = Source[i];
                        Source[i] = Source[j];
                        Source[j] = t1;
                        var t2 = Destination[i];
                        Destination[i] = Destination[j];
                        Destination[j] = t2;
                    }

            string str = "";
            for (int i = 0; i < input.Length; i++)
            {
                int index = 0;
                string st = input.Substring(i);
                while (index < Source.Length)
                {
                    if (st.StartsWith(Source[index], StringComparison.Ordinal))
                    {
                        str = str + Destination[index];
                        i += Source[index].Length - 1;
                        break;
                    }
                    index++;
                }
                if (index >= Encodings.Unicode.Value.Count)
                {
                    str = str + input[i];
                }
            }
            return str;
        }

		/// <summary>
		/// chỉ hỗ trợ unicode
		/// </summary>
        public static string ConvertToUnsign(string str)
        {
            Regex regex = new Regex("\\p{IsCombiningDiacriticalMarks}+");
            string temp = str.Normalize(NormalizationForm.FormD);
            return regex.Replace(temp, String.Empty).Replace('\u0111', 'd').Replace('\u0110', 'D');
        }

    }

    public class ItemEncoding
    {
        public ItemEncoding(string name, params string[] value)
        {
            Name = name;
            Value = new List<string>(value);
        }

        public List<string> Value { get; set; }
        public string Name { get; set; }

        public override string ToString()
        {
            return Name;
        }
    }
}